//
// Created by wujehy on 2020/8/4.
//

#ifndef AUTH_RAFT_IOTDB_H
#define AUTH_RAFT_IOTDB_H

#include "DaoBase.h"
#include <SQLiteCpp/Database.h>
#include <vector>

/**
 * @brief 传感器数据类型
 */
struct SensorDataType
{
    int64_t uid; // 用户
    uint64_t GatewayId; // 网关id
    uint64_t DeviceId; // 终端id
    int32_t permission;
    int32_t key; // key
    std::string data; // 具体数据,透传
    int64_t modifyat;
    int64_t create;
};

/**
 * @brief 设备信息数据类型
 */
struct DeviceDataType
{
    int64_t uid; // 用户
    uint64_t GatewayId; // 网关id
    uint64_t DevideId; // 终端id
    int32_t permission;
    std::string Note;
    std::string Token;
    int64_t modifyat;
    int64_t create;
};

class IoTDB : public DaoBase<void, SQLite::Database>
{
public:
    int type() override;

    int init() override;


    int initSensorDataTable();

    int initDeviceTable();

    int initGatewayTable();

    int initDeviceLoginTable();

    /**
     * @brief 添加/查找 一个网关 \n 如果 存在我的设备 则直接返回 , 否则创建
     * @param [in]uid 用户id
     * @param [out]outGid 超找到的 网关 列表
     * @return 0 -- 成功 ,  <0  --失败
     */
    int addOrFindGatewayId(int64_t uid, std::vector<uint64_t> &outGids);

    /**
     * @brief 添加 一个 设备
     * @param uid 用户id
     * @param GatewayId 网关
     * @param permission 权限
     * @param note 备注
     * @param outDeviceid 新增的 设备id
     * @return 0 -- 成功 ,  <0  --失败
     */
    int addDevice(int64_t uid, uint64_t GatewayId, int32_t permission, std::string &note, uint64_t &outDeviceid);

    int updataDeviceToken(int64_t uid, uint64_t GatewayId, uint64_t DeviceId, std::string &newToken);

    /**
     * @brief 查找设备
     * @param [out]devices
     * @param [in]uid 用户 id , 0 则查询 公开的 设备
     * @param [in]GatewayId
     * @param [in]permission
     * @return 0 -- 成功 ,  <0  --失败
     */
    int findDevices(std::vector<DeviceDataType> &devices, int64_t uid, uint64_t GatewayId, int32_t permission = 4);

    /**
     * @brief
     * @return
     */
    int insertData(SensorDataType &data);

    int findDataByUid(
            std::vector<SensorDataType> &outdatas, int64_t uid, uint64_t GatewayId = 0, uint64_t DevideId = 0,
            int32_t permission = 0, int32_t key = 0, int limit = 0, int direction = 0, int64_t targetTime = 0);

    int checkMyDevice(int64_t uid, uint64_t GatewayId, uint64_t DevideId);

    int findDataByPublic(
            std::vector<SensorDataType> &outdatas,
            uint64_t GatewayId, uint64_t DevideId,
            int size, int direction,
            int64_t targetTime);

    int loginDeviceByToken(std::string &token);

    /**
     * @brief 检验是否 登录
     * @param [in]GatewayId
     * @param [in]DevideId
     * @return
     */
    bool checkLoginDevice(uint64_t GatewayId, uint64_t DevideId, int64_t &lastLogid);

    int logoutDevice(uint64_t GatewayId, uint64_t DevideId, int64_t lastLogid);

    int HeartBeatDevice(uint64_t GatewayId, uint64_t DevideId, int64_t lastLogid);

    int findDeviceByToken(DeviceDataType &deviceDataType, std::string token);

    int findDeviceToken(DeviceDataType &deviceDataType, int64_t uid, uint64_t GatewayId, uint64_t DeviceId);

    void init_finished() override;

};


#endif //AUTH_RAFT_IOTDB_H
